<?php

namespace app\model;


use MoCommon\WeChat\Wx;
use think\facade\Config;
use think\facade\Cache;

class Util
{
    /**
     * @desc
     * 获取毫秒数
     * @author charlesyq
     * @return float
     */
    public static function getMillisecond() {
        list($t1, $t2) = explode(' ', microtime());
        return (float)sprintf('%.0f',(floatval($t1)+floatval($t2))*1000);
    }

    /**
     * @desc  获取access_token 并保存
     * @author charlesyq
     * @return mixed
     */
    public static function get_access_token()
    {
        $wechat = Config::get('app.wechat');
        $website = Config::get('app.website');
        $appid = $wechat['appid'];
        $secret = $wechat['secret'];

        $options = Config::get('app.converse');
        $redis = Cache::init($options);

        Wx::init([$appid, $secret]);

        // 获取基础 access_token
        $access_token = $redis->get($website['index'] . '_access_token');

        if (empty($access_token)) {
            $access = Wx::access_token();
            $access_token = $access['access_token'];
            $redis->set($website['index'] . '_access_token', $access_token, $access['expires_in'] - 300);
        }
        return $access_token;
    }

    /**
     * @desc  更新 access_token 并保存
     * @author charlesyq
     * @return mixed
     */
    public static function update_access_token()
    {

        $options = Config::get('app.converse');
        $redis = Cache::init($options);
        $website = Config::get('app.website');
        $access = Wx::access_token();
        $access_token = $access['access_token'];
        $redis->set($website['index'] . '_access_token', $access_token, $access['expires_in'] - 300);
        return $access_token;
    }




    /**
     * @desc  获取其他账户的 access_token 并保存
     * @author charlesyq
     * @return mixed
     */
    public static function get_other_access_token($appid,$secret){


        $cache = Di::getDefault()->getShared('cache');
        Wx::init([$appid, $secret]);

        // 获取基础 access_token
        $access_token = $cache->get($appid.'_access_token');

        if(empty($access_token)){
            $access = Wx::access_token();
            $access_token = $access['access_token'];
            $cache->setEx($appid.'_access_token', $access['expires_in'] - 300, $access_token);
        }

        return $access_token;

    }

    /**
     * @desc  更新 其他账户的 access_token 并保存
     * @author charlesyq
     * @return mixed
     */
    public static function update_other_access_token($appid,$secret){


        $cache = Di::getDefault()->getShared('cache');
        Wx::init([$appid, $secret]);
        $access = Wx::access_token();
        $access_token = $access['access_token'];
        $cache->setEx($appid.'_access_token', $access['expires_in'] - 300, $access_token);

        return $access_token;

    }




    /**
     * @param $appid
     * @desc
     * 获取access_token 并保存
     * @author charlesyq
     * @return string
     */
    public static function get_authorizer_access_token($appid){

        global $config;

        $data = [
            'component_app_id'=>$config->wechat->component_appid,
            'component_app_secret'=>$config->wechat->component_app_secret,
            'app_id'=>$appid,
        ];

        $url = "http://admin.kankanyisheng.com/wechat/thirdpart/gettoken";

        $json = Wx::parsePostJson($url,$data);

        if(empty($json['token'])){
            return '';
        }else{
            return $json['token'];
        }


    }


    /**
     * @desc
     * 获取access_token 并保存
     * @author charlesyq
     * @return string
     */
    public static function get_component_access_token(){

        global $config;

        $data = [
            'component_app_id'=>$config->wechat->component_appid,
            'component_app_secret'=>$config->wechat->component_app_secret,
        ];

        $url = "http://admin.kankanyisheng.com/wechat/thirdpart/get_component_access_token";

        $json = Wx::parsePostJson($url,$data);

        if(empty($json['token'])){
            return '';
        }else{
            return $json['token'];
        }


    }



    /**
     * @desc  获取access_token 并保存
     * @author charlesyq
     * @return mixed
     */
    public static function get_sp_access_token($administrative_id){

        global $config;

        $cache = Di::getDefault()->getShared('cache');

        $administrative = AppnameZhaoyishengAdministrative::findFirst("id = $administrative_id");

        if($administrative){
            // 获取基础 access_token
            $access_token = $cache->get($config->website->index.'_access_token_'.$administrative_id);

            if(empty($access_token)){
                $access = Wx::sp_access_token($administrative->appid,$administrative->appsecret);
                $access_token = $access['access_token'];
                $cache->setEx($config->website->index.'_access_token_'.$administrative_id, $access['expires_in'] - 60, $access_token);
            }

            return $access_token;
        }else{
            return '';
        }



    }

    /**
     * @desc 测试环境获取正式环境openid （用户测试微信支付）
     * @author charlesyq
     * @return array
     */
    public static function testOpenids(){

        global $config;

        if ($config->env->debug) {
            $arr = [
                7174 => 'o3yuWwzydYnfnHcRhzTnnp8rGmpU',  //杨琪
                7173 => 'o3yuWw4tfP26kRBtEJS_nFPI_03w',  //weiChen
                7171 => 'o3yuWw1APEf-WmJoHETLjlT6nWbc',  //徐越峰
                7175 => 'o3yuWw_Z40x2JFubVGL-bJU6ohE4',  //susan
                7176 => 'o3yuWw60dIk6gk8eINfwcQKC_Rx4',  //北隐_BEIYIN
                7180 => 'o3yuWw0j6sA3wcjg3ax55EIX8sYA',  //小看
                7181 => 'o3yuWw8jP_uwvexw0Dxwr9Knfdjs',  //月隐伤
                7199 => 'o3yuWw4GdRhzNsEYl0haxi7b41Kg',  //bunny
                7200 => 'o3yuWwx2kVOO4oAzAq2HypGGNpps',  //静以修身
                7197 => 'o3yuWwxesbaiZXbI5q0-dImb7h70',  //曾天昊
            ];
        }else{
            $arr = [];
        }

        return $arr;
    }

    /**
     * @desc  获取dicom  token
     * @author charlesyq
     * @return string
     */
    public static function get_dicom_token(){

        global $config;
        $cache = Di::getDefault()->getShared('cache');
        $access_token = $cache->get($config->website->index.'_access_token_weiyun');

        if(empty($access_token)){
            $auth_url = $config->website->weiyun_url.'oauth/token';
            $access  = self::parsePostJson($auth_url,['grant_type'=>'client_credentials'],["Authorization: Basic a2Fua2FuOlBhNTV3b3JkIQ=="]);
            $access_token = $access['access_token'];
            $cache->setEx($config->website->index.'_access_token_weiyun', $access['expires_in'] - 60, $access_token);
        }

        return $access_token;



    }

    /**
     * @param $uid
     * @desc  获取dicom信息
     * @author charlesyq
     * @return  bool|mixed
     */
    public static function get_dicom_info($uid){

        global $config ;

        $token = self::get_dicom_token();

        $info_url = $config->website->weiyun_url."r/open/study/{$uid}";
        $header[] = "Content-Type:application/json";
        $header[] = "Authorization: Bearer $token";

        $info = self::parseJson($info_url,$header);

        return $info;

    }


    /**
     * @desc  获取上传的storeUid
     * @author charlesyq
     * @return string
     */
    public static function get_storeUid(){

        global $config ;

        $info_url = $config->website->weiyun_url."r/open/store/uid";
        $info = self::parseJson($info_url);

        return empty($info['storeUid']) ? '' :$info['storeUid'];

    }
    /**
     * @param $uid
     * @desc 上传dicom 影像
     * @author charlesyq
     * @return bool
     */
    public static function upload_dicom($uid){

        global $config ;

        $upload_url = $config->website->weiyun_url."r/open/store";

        $data = [
            'storeUid'=> $uid,
            'owner'   => 'kankan'
        ];
        $data = json_encode($data);
        $result1 = self::parsePostJson($upload_url,$data,['Content-Type: application/json']);

        $uploaded_url = $config->website->weiyun_url."r/open/store/uploaded";
        $result2 = self::parsePostJson($uploaded_url,[
            'storeUid'=>$uid
        ]);
        Di::getDefault()->getShared('logger')->log("微云上传dicom请求返回:" . json_encode($result1));
        Di::getDefault()->getShared('logger')->log("微云上传dicom成功后请求返回:" . json_encode($result2));

        return ($result1['status']=='SUCCESS') && ($result2['status']=='SUCCESS') ;
    }




    public static function send_question_template($send_members ,$question_data,$message="您好,平台发布了一个新提问,快来查看吧"){

        global $config;

        //推送模板消息
        if($send_members){
            $access_token = Util::get_access_token();

            $tpl_id = $config->wechat->onetoone_tpl_id;

            //回答问题信息
            $question_addtime =Helper::format_date($question_data['addtime']);

            if($question_data['type']==QuestionLogType::PAY_TO_SEE){
                $url = $config->website->index.'#detail2/'.$question_data['question_id'];
            }else{
                $url = $config->website->index.'#detail/'.$question_data['question_id'];
            }


            $to_user_data = array(
                'first'=>array('value'=>urlencode($message),'color'=>"#743A3A"),
                'keyword1'=>array('value'=>urlencode($question_data['question'])),
                'keyword2'=>array('value'=>urlencode($question_addtime)),
                'keyword3'=>array('value'=>urlencode($question_data['description'])),
                'keyword4'=>array('value'=>urlencode($question_addtime)),
                'remark'=>array('value'=>urlencode('详情请点击此处')),
            );
            //Wx::init(['wx49a8b6c3e4bc8c66', '72ed3a614d17d77bc7e5f20e886d26b1']);
            Wx::init([$config->wechat->appid, $config->wechat->secret]);

//            Di::getDefault()->getShared('logger')->log("发送模板消息内容:" . json_encode($to_user_data));
//            Di::getDefault()->getShared('logger')->log("发送模板消息用户:" . json_encode($send_members));


            //发消息给所有关注的用户
            if($send_members == 'all'){

                $log = Di::getDefault()->getShared('logger');

                $time = time();
                $is_last = false;
                $next_openid = '';

                while(!$is_last){

                    $data = Wx::cgi_user_get($access_token,$next_openid);

                    if($data['count']<10000){
                        $is_last = true;
                    }

                    if(isset($data['data']['openid'])){

                        $next_openid = $data['next_openid'];

                        foreach (self::openidArray($data['data']['openid']) as $openid){

                            $tpl_ret = Wx::send_template($access_token, $url, $openid, $tpl_id, $to_user_data);

                            if ($tpl_ret['errcode'] != 0) {
                                AppnameLogs::insertOne([
                                    "info"  => "微信模板消息errcode: {$tpl_ret['errcode']}",
                                    "type"  => LogsType::WECHAT,
                                    'actor' => __FUNCTION__,
                                ]);
                            }
                        }



                    }else{
                        $is_last = true;
                    }


                }
                $log->info("发送模板消息共用时：".(time()-$time));

            }else{
                foreach ($send_members as $send_member){
                    $tpl_ret = Wx::send_template($access_token, $url, $send_member['openid'], $tpl_id, $to_user_data);

                    if ($tpl_ret['errcode'] != 0) {
                        AppnameLogs::insertOne([
                            "info"  => "微信模板消息errcode: {$tpl_ret['errcode']}",
                            "type"  => LogsType::WECHAT,
                            'actor' => __FUNCTION__,
                        ]);
                    }
                }
            }



        }
    }


    private  static function openidArray($array){

        for ($i = 0; $i <= count($array); $i ++) {

            yield $array[$i];
        }
    }





    public static  function parsePostJson($url = '', $param = '',$header=[])
    {
        if (empty($url) || empty($param)) {
            return false;
        }

        $curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => "POST",
            CURLOPT_POSTFIELDS => $param,
            CURLOPT_HTTPHEADER => $header,
        ));

        $data = curl_exec($curl); //运行curl
        curl_close($curl);

        return json_decode($data, TRUE);

    }

    public static  function parseJson($url = '',$header=[])
    {
        if (empty($url)) {
            return false;
        }

        $curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => "GET",
            CURLOPT_HTTPHEADER => $header,
        ));

        $data = curl_exec($curl); //运行curl
        curl_close($curl);

        return json_decode($data, TRUE);

    }


    /**
     * @param $phone
     * @desc  发送短信接口，目前暂用商脉
     * @author charlesyq
     * @return mixed
     */
    public static function sendMessage($phone){

        global $config;

        $code = 0;

        $url = ($config->website->yiku_api).'Apiuser/verify';


        $result = Wx::parsePostJson($url,['userphone'=>$phone]);
        //发送返回值的判断
        if(isset($result['mediCode'])&&$result['mediCode']==10000){
            AppnameLogs::insertOne([
                "info"  => "给手机号 $phone 发送短信成功",
                "type"  => LogsType::SIMPLE,
                'actor' => __FUNCTION__,
            ]);
            $code = $result['mediData']['phonecode'];
            $msg = '发送成功';

        }else{
            $msg=$result['mediMsg'];
            $result = json_encode($result);
            AppnameLogs::insertOne([
                "info"  => "发送短信失败: {$result}",
                "type"  => LogsType::SIMPLE,
                'actor' => __FUNCTION__,
            ]);

        }
        return [
            'code' =>$code,
            'msg' =>$msg
        ];
    }



    /**
     * @param $info
     * 二维码信息
     * @param bool|false $is_temp
     * 是否是临时二维码
     * @param int $expires_in
     * 临时二维码过期时间
     * @desc
     * 调用微信接口生成二维码
     *
     * @author charlesyq
     * @return string
     * 返回二维码url
     */
    public static function iniActionQrCode($info,$size=6,$is_temp=false,$expires_in=2592000){

        global $config;

        $access_token = Util::get_access_token();
        Wx::init([$config->wechat->appid, $config->wechat->secret]);
        $url = '';


        $need_draw_qr = true;
        if($is_temp){
            $cache = Di::getDefault()->getShared('cache');

            $url = $cache->get($config->website->index.'_wxqr_'.$info);

            if(!$url){
                $tpl_ret = Wx::qrcode_tmp_create($access_token,$info);
                $cache->setEx($config->website->index.'_wxqr_'.$info, $expires_in - 60, $tpl_ret['url']);
            }else{
                $need_draw_qr = false;
            }


        }else{
            $tpl_ret = Wx::qrcode_forever_create($access_token,$info);
        }

        if(isset($tpl_ret)){
            if ($tpl_ret['errcode'] != 0) {
                AppnameLogs::insertOne([
                    "info"  => "微信模板消息errcode: {$tpl_ret['errcode']}",
                    "type"  => LogsType::WECHAT,
                    'actor' => __FUNCTION__,
                ]);
                //$data = $config->website->index."#/otherInfo/$user_id";
            }else{
                $url = $tpl_ret['url'];
            }
        }

        if($need_draw_qr){
            self::create_qr_image($info,$url,$size);
        }


        return $url;

    }

    /**
     * @param $name
     * 二维码名字
     * @param $url
     * 二维码url
     * @param int $matrixPointSize
     * 二维码大小
     * @desc
     * 生成 二维码
     * @author charlesyq
     * @return void
     */
    public static function create_qr_image($name,$url,$matrixPointSize=6){

        // 生成的文件名
        $filename =APP_PATH."/public/images/qr/{$name}.png";
        // 纠错级别：L、M、Q、H
        $errorCorrectionLevel = 'H';
        // 点的大小：1到10
        QRcode::png($url, $filename, $errorCorrectionLevel, $matrixPointSize, 2);

    }



    /**
     * @param $info
     * 二维码信息
     * @param bool|false $is_temp
     * 是否是临时二维码
     * @param int $expires_in
     * 临时二维码过期时间
     * @desc
     * 调用微信接口生成二维码
     *
     * @author charlesyq
     * @return string
     * 返回二维码url
     */
    public static function iniOtherActionQrCode($appid,$secret,$info,$size=6,$is_temp=false,$expires_in=2592000){

        Wx::init([$appid, $secret]);

        $access_token = Util::get_access_token();

        $url = '';


        $need_draw_qr = true;
        if($is_temp){
            $cache = Di::getDefault()->getShared('cache');

            $url = $cache->get($appid.'_wxqr_'.$info);

            if(!$url){
                $tpl_ret = Wx::qrcode_tmp_create($access_token,$info);
                $cache->setEx($appid.'_wxqr_'.$info, $expires_in - 60, $tpl_ret['url']);
            }else{
                $need_draw_qr = false;
            }


        }else{
            $tpl_ret = Wx::qrcode_forever_create($access_token,$info);
        }

        if(isset($tpl_ret)){
            if ($tpl_ret['errcode'] != 0) {
                AppnameLogs::insertOne([
                    "info"  => "微信模板消息errcode: {$tpl_ret['errcode']}",
                    "type"  => LogsType::WECHAT,
                    'actor' => __FUNCTION__,
                ]);
                //$data = $config->website->index."#/otherInfo/$user_id";
            }else{
                $url = $tpl_ret['url'];
            }
        }

        if($need_draw_qr){
            self::create_qr_image($info,$url,$size);
        }


        return $url;

    }



    public static function getYikuPem(){

        return '-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5uwYIvYbmCHF+siWBk4U
pTZHz8NZyonxEgPLcATmWcFu+yeEPEUTgb7hbO78Huuq7e9+HqM2xlDqReeD94Yp
Nv6rhjQ3AQsx4tlEwaFzZtcVOPiMZRP87b4ljP+6olLB3GeS9gfKg8r/UpoZet0o
+Tb/E6zFODZx2dTCxKC9p0IPpAiVgUTYqUNL3dVNgIKnrG1Y9BFtvC5JeWZj96L9
KCIXcDYrZIOVqTGmmcIRrdRYeBfVVQmMpnVaic2asD1QCVwL3IFEWRdzex31R+lx
kbFlf/yEZGJ16AZED/+VTfOsvNr75uKZEwVsUxdiNBmwoIEGQ/hm9oFpbSDxWepy
qwIDAQAB
-----END PUBLIC KEY-----
';
    }


    public static function getYikuFlow($member_id){


        global $config;

        $cache = Di::getDefault()->getShared('cache');

        // 获取基础 access_token
        $flow = $cache->get($config->website->index."_{$member_id}_flow");

        if(empty($flow)){
            $flow = self::getYikuFlowApi($member_id);
            $cache->setEx($config->website->index."_{$member_id}_flow", 300, $flow);
        }

        return $flow;
    }


    public static function getYikuFlowApi($member_id)
    {

        global $config;


        if(!$member_id){

            AppnameLogs::insertOne([
                "info" => "获取积分errcode: member_id 为空",
                "type" => LogsType::WECHAT,
                'actor' => __FUNCTION__,
            ]);
            return 0;
        }
        $member = AppnameMMembers::findFirst("id = $member_id");
        $member = $member ? $member->toArray():[];

        $url = ($config->website->yiku_api) . 'Apiuser/getflow';

        $post_data = [
            'userid' => $member['yiku_id'],
            'key' => 'medicoolyikan2017'

        ];

        $result = Wx::parsePostJson($url, $post_data);


        if (isset($result['mediCode']) && $result['mediCode'] == 10000) {


            return $result['mediData']['UserFlow'];
        } else {
            $error_content = json_encode($result);
            $param = json_encode($post_data);
            AppnameLogs::insertOne([
                "info" => "获取积分errcode: {$error_content}----参数:{$param}",
                "type" => LogsType::WECHAT,
                'actor' => __FUNCTION__,
            ]);

            return 0;
        }


    }

    public static function updateYikuFlow($member_id, $integral, $datatype,$type,$record_id,$info)
    {

        global $config;

        if(!$member_id){
            AppnameLogs::insertOne([
                "info" => "更新积分errcode: member_id 为空",
                "type" => LogsType::WECHAT,
                'actor' => __FUNCTION__,
            ]);
            return  -10000;
        }
        $member = AppnameMMembers::memberExists("id = $member_id");

        $url = ($config->website->yiku_api) . 'Apiuser/updateflow';

        $post_data = [
            'userid' => $member['yiku_id'],
            'key' => 'medicoolyikan2017',
            'integral' => $integral,
            'datatype' => $datatype,
            'type'=>$type,
            'record_id'=>$record_id,
            'info'=>$info,


        ];

        $result = Wx::parsePostJson($url, $post_data);


        $error_content = json_encode($result);
        $param = json_encode($post_data);
        if (isset($result['mediCode']) && $result['mediCode'] == 10000) {
            $info = ($member['yiku_id'].'积分变动'.($datatype==1?'-':'').$integral." 结果: {$error_content}----参数:{$param}");
            $flag = true;
        } else {

            $info = "变动积分errcode: {$error_content}----参数:{$param}";
            $flag = false;
        }


        AppnameLogs::insertOne([
            "info" => $info,
            "type" => LogsType::WECHAT,
            'actor' => __FUNCTION__,
        ]);
        return $flag;

    }

    /**
     * @param $total
     * @param $num
     * @param $min
     * @desc
     * 生成随机红包
     * @author charlesyq
     * @return array
     */
    public static function reward_array($total,$num,$min){

        $array = [];
        for ($i=1;$i<$num;$i++)
        {
            $safe_total=($total-($num-$i)*$min)/($num-$i);//随机安全上限
            $money=mt_rand($min*100,$safe_total*100)/100;
            $array[] = $money;
            $total=$total-$money;
        }
        $array[] = $total;

        shuffle($array);

        return $array;
    }










}

